package hotel.switchs.oversea.biz.config;//package hotel.switchs.oversea.biz.config;
//
//import com.alibaba.fastjson.JSON;
//import hotel.base.oversea.constant.CommonConstants;
//import hotel.base.oversea.constant.CommonUrlConstants;
//import hotel.base.oversea.constant.enums.AspectEnums;
//import hotel.base.oversea.utils.DateUtil;
//import hotel.base.oversea.utils.Result;
//import hotel.switchs.oversea.api.entity.SysApiLog;
//import hotel.switchs.oversea.biz.task.SwitchsSaveApiLogTask;
//import lombok.extern.slf4j.Slf4j;
//import org.aspectj.lang.JoinPoint;
//import org.aspectj.lang.ProceedingJoinPoint;
//import org.aspectj.lang.annotation.*;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.context.annotation.Configuration;
//import org.springframework.http.HttpEntity;
//import org.springframework.http.HttpHeaders;
//import org.springframework.http.MediaType;
//import org.springframework.web.client.RestTemplate;
//
//import javax.servlet.http.HttpServletRequest;
//import java.lang.reflect.UndeclaredThrowableException;
//import java.util.Date;
//import java.util.UUID;
//
//@Configuration
//@Aspect
//@Slf4j
//public class ServiceAspect {
//    @Autowired
//    RestTemplate restTemplate;
//    @Autowired
//    SwitchsSaveApiLogTask switchsSaveApiLogTask;
//
//    private HttpServletRequest request;
//    //private final String ExpGetResultDataPonit = "execution(* hotel.meituan.biz.controller.*.*(..))";
//    private final String ExpGetResultDataPonit = "execution(* hotel.switchs.oversea.biz.controller.*.asp*(..))";
//    //execution(* com...*Service+.*(..)) and !execution(* Object.*(..))
//
//    //定义切入点,拦截servie包其子包下的所有类的所有方法
////    @Pointcut("execution(* hotel*.service..*.*(..))")
//    //拦截指定的方法,这里指只拦截SysUserService.findByName这个方法
//    @Pointcut(ExpGetResultDataPonit)
//    public void excuteService() {
//        System.out.printf("=====excuteService ");
//    }
//
//    /**
//     * 环绕通知：
//     * 环绕通知非常强大，可以决定目标方法是否执行，什么时候执行，执行时是否需要替换方法参数，执行完毕是否需要替换返回值。
//     * 环绕通知第一个参数必须是org.aspectj.lang.ProceedingJoinPoint类型
//     */
//    @Around(ExpGetResultDataPonit)
//    public Object doAroundAdvice(ProceedingJoinPoint proceedingJoinPoint) {
//        //System.out.println("doAroundAdvice 环绕通知的目标方法名：" + proceedingJoinPoint.getSignature().getName());
//        String mapping = proceedingJoinPoint.getSignature().getDeclaringType().getName()+"."+proceedingJoinPoint.getSignature().getName();//hotel.meituan.biz.controller.MtHotelOrderNotifyController.aspRpCallback
//        String method = proceedingJoinPoint.getSignature().getName();
//        String paramsJson = proceedingJoinPoint.getArgs()==null?null:proceedingJoinPoint.getArgs()[0].toString();//方法请求参数是对象而上送的参数无法转成对象时，当前接收到的请求参数为空
//        //processInputArg(proceedingJoinPoint.getArgs());
//        Object obj = null;
//        try {//obj之前可以写目标方法执行前的逻辑
//            obj = proceedingJoinPoint.proceed();//调用执行目标方法
//            //processOutPutObj(obj);
//        } catch (Throwable throwable) {
//            obj = new Result<>(DateUtil.getCurrTime()+"  Switchs ServiceAspect-proceedingJoinPoint.proceed()-调用接口异常请核实！method:"+method,CommonConstants.REQUEST_ERROR);
//            log.error("切面拦截 ServiceAspect  异常 proceedingJoinPoint.proceed() error method:"+method+",,,,,,"+getMessage(throwable));
//            throwable.printStackTrace();
//        }
//        SysApiLog sysApiLog = new SysApiLog();
//        sysApiLog.setId(UUID.randomUUID().toString());
//        sysApiLog.setSystemName(method);
//        sysApiLog.setClassName(AspectEnums.jobMethod.getName(method));
//        sysApiLog.setRemark(mapping);
//        sysApiLog.setJson(obj==null?null:obj.toString());
//        sysApiLog.setParamJson(paramsJson);
//        sysApiLog.setCreateTime(new Date());
//        sysApiLog.setModifyTime(sysApiLog.getCreateTime());
//        try{
//            switchsSaveApiLogTask.execute(sysApiLog);
//        }catch (Exception e){
//            log.error("携程 ServiceAspect 异步线程保存日志异常 ："+e.getMessage());
//            e.printStackTrace();
//        }
//
//        //获取返回参数
//        return obj;
//    }
//
//    public static String getMessage(Throwable e){
//        String msg = null;
//
//        try {
//            if (e instanceof UndeclaredThrowableException){
//                Throwable targetEx = ((UndeclaredThrowableException) e).getUndeclaredThrowable();
//                if (targetEx != null){
//                    msg = targetEx.getMessage();
//                }
//            } else {
//                msg = e.getMessage();
//            }
//        }catch (Exception e2){
//            log.error("ServiceAspect getMessage 异常:"+e2.getMessage());
//            e2.printStackTrace();
//        }
//
//
//        return msg;
//    }
//
//
//    /**
//     * 处理输入参数
//     *
//     * @param args 入参列表
//     */
//    private void processInputArg(Object[] args) {
//        for (Object arg : args) {
//            //System.out.println("processInputArg ARG原来为:" + arg);
//        }
//    }
//
//
//    //执行方法前的拦截方法
//    @Before("excuteService()")
//    public void doBeforeMethod(JoinPoint joinPoint) {
//        //System.out.printf("doBeforeMethod");
//        //获取目标方法的参数信息
////        Object[] obj = joinPoint.getArgs();
////        for (Object argItem : obj) {
////            System.out.println("---->now-->argItem:" + argItem);
////            System.out.println("---->after-->argItem:" + argItem);
////        }
//    }
//
//    /**
//     * 处理返回对象
//     */
//    private void processOutPutObj(Object obj) {
//        System.out.println("processOutPutObj OBJ 原本为：" + obj.toString());
////        if (obj instanceof Result) {
////            Result resultVO = (Result) obj;
////            resultVO.setMsg("哈哈，我把值修改了" + resultVO.getMsg());
////            System.out.println(resultVO);
////        }
//    }
//
//
//    /**
//     * 后置最终通知（目标方法只要执行完了就会执行后置通知方法）
//     */
//    @After("excuteService()")
//    public void doAfterAdvice(JoinPoint joinPoint) {
//
////        System.out.println("doAfterAdvice 后置通知执行了!!!!");
//    }
//
//
//    /**
//     * 后置返回通知
//     * 这里需要注意的是:
//     * 如果参数中的第一个参数为JoinPoint，则第二个参数为返回值的信息
//     * 如果参数中的第一个参数不为JoinPoint，则第一个参数为returning中对应的参数
//     * returning 限定了只有目标方法返回值与通知方法相应参数类型时才能执行后置返回通知，否则不执行，对于returning对应的通知方法参数为Object类型将匹配任何目标返回值
//     */
//    @AfterReturning(value = ExpGetResultDataPonit, returning = "keys")
//    public void doAfterReturningAdvice1(JoinPoint joinPoint, Object keys) {
////        System.out.println("doAfterReturningAdvice1 第一个后置返回通知的返回值：" + keys);
////        if (keys instanceof Result) {
////            Result resultVO = (Result) keys;
////            String message = (String) resultVO.getMsg();
////            resultVO.setMsg("通过AOP把值修改了 " + message);
////        }
////        System.out.println("修改完毕-->返回方法为:" + keys);
//    }
//
//
//
//
//
//}
